#pragma once

#include <uv.h>
#include <anb/common/utils.h>

#include "connection_base.h"
#include "packet.h"

namespace anb { namespace net {

class loop_action {
public:
	enum type {
		type_write_packet = 1,
	};

	static loop_action* create(type type);
	static void destroy(loop_action* action);

	loop_action(type type);
	~loop_action();

	type get_type();

protected:

	static void async_callback(uv_async_t* async);
	virtual void act() = 0;

private:
	type m_type;
};


class write : public loop_action {
public:

	write(type type);
	~write();

	void init(connection_base::ptr connection);
	virtual void act();

	virtual size_t size() = 0;
	virtual uv_buf_t* get() = 0;

	uv_write_t* get_write();

private:
    connection_base::ptr m_connection;
	uv_write_t m_write;
};

class packet_write : public write
{
public:
	enum index {
		index_len = 0,
		index_packet,
		index_body,

		index_max,
	};

	packet_write();
	~packet_write();

	void init(connection_base::ptr connection, size_t body_len);

	virtual size_t size();

	virtual uv_buf_t* get();

	char* get_packet();
	char* get_body();
	
private:
	uv_buf_t m_bufs[3];
	char m_len[connection_base::LEN_SIZE];
	char m_packet[packet::SIZE];
};


} }
